:- ['framework/primitives.pl'].

ce(ctxm(_,_,_,_,X),ctxm(_,_,_,_,X)).
ce([],[]).
ce([X1|LST1],[X2|LST2]) :- ce(X1,X2), ce(LST1,LST2).
ce(pri(T,L1),pri(T,L2)) :- ce(L1,L2).

contains(X,X).
contains(pri(_,L),Y) :- member(I,L), contains(I,Y).

containsn(0,X,X).
containsn(NP1,pri(_,L),Y) :- member(I,L), containsn(N,I,Y), NP1 is N+1.


subsets([], []).
subsets([E|Tail], [E|NTail]):-
  subsets(Tail, NTail).
subsets([_|Tail], NTail):-
  subsets(Tail, NTail).
nesub(X,LST) :- subsets(LST,X), X\=[].


hasdomain(D,ctxm(D,_,_,_,_)).
hasdomain(_,[]).
hasdomain(D,[X|LST]) :- hasdomain(D,X), hasdomain(D,LST).
hasdomain(D,pri(_,M)) :- hasdomain(D,M).

cons(omega,_) :- !.
cons(A,X) :- der(A,X).
cons(_,[]).
cons(A,[X|LST]) :- cons(A,X), cons(A,LST).
cons(A,M) :- consneeded(M,MP), cons(A,MP).


know(I,M) :- knows(I,M).
know(L,M) :- member(A,L), know(A,M).

% knowledge of (a,pi_): also stored knowledge of a
know((A,PI),M) :- PI\=s, know((A,s),M).
know(A,M) :- atomic(A), know((A,_),M).

hasproperty2(_,_,_) :- not(current_predicate(hasproperty/3)), !, fail.
hasproperty2(A,B,C) :- hasproperty(A,B,C).